#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <cstdio>
#include <iostream>
#include <QObject>
#include <QAction>
#include <QApplication>
#include <QLabel>
#include <QSlider>
#include <QColor>
#include <QLineEdit>
#include <QPushButton>
#include <QClipboard>
#include <QMimeData>
#include <QString>
#include <QStringList>

using namespace std;

int R = 255;
int G = 255;
int B = 255;
int CMYK_C = 0;
int CMYK_M = 0;
int CMYK_Y = 0;
int CMYK_K = 0;

QString HEXQString;

class myWindow : public QWidget
{
Q_OBJECT
public:
	myWindow(void);
protected:
	QLabel *colorLabel;
	QLabel *websafeLabel;
	QLabel *hexColorLabel;
	QLineEdit *hexColorLine;
	QLabel *hexWebSafeLabel;
	QLabel *hexWebSafeValueLabel;
	QPushButton *copyFullHexValue;
	QPushButton *pasteFullHexValue;
	QPushButton *copyWebsafeHexValue;
	QLineEdit *r_Line;
	QLineEdit *g_Line;
	QLineEdit *b_Line;
	QLabel *r_Label;
	QLabel *g_Label;
	QLabel *b_Label;
	QSlider *r_Slider;
	QSlider *g_Slider;
	QSlider *b_Slider;
	QLabel *CMYK_C_Label;
	QLabel *CMYK_M_Label;
	QLabel *CMYK_Y_Label;
	QLabel *CMYK_K_Label;
	QLineEdit *CMYK_C_Line;
	QLineEdit *CMYK_M_Line;
	QLineEdit *CMYK_Y_Line;
	QLineEdit *CMYK_K_Line;
public slots:
	void colorLabelUpdateR(int);
	void colorLabelUpdateG(int);
	void colorLabelUpdateB(int);
	void fullHexChanged(QString);
	void pasteFullHex(void);
	void copyWebsafeHex(void);
	void copyFullHex(void);
	QString webSafe(void);
	void updateSlider(void);
	void updateCMYK(void);
	void CMYK_C_Edited(void);
	void CMYK_M_Edited(void);
	void CMYK_Y_Edited(void);
	void CMYK_K_Edited(void);
	void RGB_R_Edited(void);
	void RGB_G_Edited(void);
	void RGB_B_Edited(void);
	void updateFromRGB(void);
	void updateFromCMYK(void);
};


QString getRGB();
QString getHEX();
QString getCMYK();

myWindow::myWindow(void) {
	this->resize(400, 400);
	colorLabel = new QLabel(this);
        colorLabel->setGeometry(QRect(20, 20, 100, 100));
        colorLabel->setFrameShape(QFrame::Box);
	colorLabel->setStyleSheet("background-color: rgb(255, 255, 255);");
	websafeLabel = new QLabel(this);
	websafeLabel->setGeometry(QRect(70, 70, 50, 50));
	websafeLabel->setFrameShape(QFrame::Box);
	websafeLabel->setStyleSheet("background-color: rgb(255, 255, 255);");
	hexColorLabel = new QLabel(this);
	hexColorLabel->setGeometry(QRect(160, 30, 70, 20));
	hexColorLabel->setText("Hexvalue:");
	hexColorLine = new QLineEdit(this);
	hexColorLine->setGeometry(QRect(235, 25, 80, 30));
	hexColorLine->setText("#ffffff");
	hexColorLine->setMaxLength(7);
	hexColorLine->setInputMask("XHHHHHH");
	hexWebSafeLabel = new QLabel(this);
	hexWebSafeLabel->setGeometry(QRect(160, 90, 75, 20));
	hexWebSafeLabel->setText("Websafe:");
	hexWebSafeValueLabel = new QLabel(this);
	hexWebSafeValueLabel->setGeometry(QRect(245, 90, 95, 20));
	hexWebSafeValueLabel->setText("#ffffff");
	copyFullHexValue = new QPushButton(this);
	copyFullHexValue->setGeometry(QRect(320, 20, 60, 25));
	copyFullHexValue->setText("Copy");
	pasteFullHexValue = new QPushButton(this);
	pasteFullHexValue->setGeometry(QRect(320, 46, 60, 25));
	pasteFullHexValue->setText("Paste");
	copyWebsafeHexValue = new QPushButton(this);
	copyWebsafeHexValue->setGeometry(QRect(320, 85, 60, 25));
	copyWebsafeHexValue->setText("Copy");
	r_Slider = new QSlider(this);
        r_Slider->setGeometry(QRect(20, 150, 256, 20));
	r_Slider->setMaximum(255);
        r_Slider->setOrientation(Qt::Horizontal);
	r_Slider->setValue(255);
	g_Slider = new QSlider(this);
        g_Slider->setGeometry(QRect(20, 180, 256, 20));
	g_Slider->setMaximum(255);
        g_Slider->setOrientation(Qt::Horizontal);
	g_Slider->setValue(255);
	b_Slider = new QSlider(this);
        b_Slider->setGeometry(QRect(20, 210, 256, 20));
	b_Slider->setMaximum(255);
        b_Slider->setOrientation(Qt::Horizontal);
	b_Slider->setValue(255);
	r_Label = new QLabel(this);
	r_Label->setGeometry(QRect(325, 150, 20, 20));
	r_Label->setText("R:");
	g_Label = new QLabel(this);
	g_Label->setGeometry(QRect(325, 180, 20, 20));
	g_Label->setText("G:");
	b_Label = new QLabel(this);
	b_Label->setGeometry(QRect(325, 210, 20, 20));
	b_Label->setText("B:");
	r_Line = new QLineEdit(this);
	r_Line->setGeometry(QRect(347, 145, 35, 30));
	r_Line->setText("255");
	r_Line->setMaxLength(3);
	r_Line->setInputMask("000");
	g_Line = new QLineEdit(this);
	g_Line->setGeometry(QRect(347, 175, 35, 30));
	g_Line->setText("255");
	g_Line->setMaxLength(3);
	g_Line->setInputMask("000");
	b_Line = new QLineEdit(this);
	b_Line->setGeometry(QRect(347, 205, 35, 30));
	b_Line->setText("255");
	b_Line->setMaxLength(3);
	b_Line->setInputMask("000");
	CMYK_C_Label = new QLabel(this);
	CMYK_C_Label->setGeometry(QRect(20, 245, 20, 20));
	CMYK_C_Label->setText("C:");
	CMYK_M_Label = new QLabel(this);
	CMYK_M_Label->setGeometry(QRect(122, 245, 20, 20));
	CMYK_M_Label->setText("M:");
	CMYK_Y_Label = new QLabel(this);
	CMYK_Y_Label->setGeometry(QRect(224, 245, 20, 20));
	CMYK_Y_Label->setText("Y:");
	CMYK_K_Label = new QLabel(this);
	CMYK_K_Label->setGeometry(QRect(325, 245, 20, 20));
	CMYK_K_Label->setText("K:");
	CMYK_C_Line = new QLineEdit(this);
	CMYK_C_Line->setGeometry(QRect(42, 240, 35, 30));
	CMYK_C_Line->setText("0");
	CMYK_C_Line->setMaxLength(3);
	CMYK_C_Line->setInputMask("000");
	CMYK_M_Line = new QLineEdit(this);
	CMYK_M_Line->setGeometry(QRect(144, 240, 35, 30));
	CMYK_M_Line->setText("0");
	CMYK_M_Line->setMaxLength(3);
	CMYK_M_Line->setInputMask("000");
	CMYK_Y_Line = new QLineEdit(this);
	CMYK_Y_Line->setGeometry(QRect(246, 240, 35, 30));
	CMYK_Y_Line->setText("0");
	CMYK_Y_Line->setMaxLength(3);
	CMYK_Y_Line->setInputMask("000");
	CMYK_K_Line = new QLineEdit(this);
	CMYK_K_Line->setGeometry(QRect(347, 240, 35, 30));
	CMYK_K_Line->setText("0");
	CMYK_K_Line->setMaxLength(3);
	CMYK_K_Line->setInputMask("000");
	QObject::connect(r_Slider, SIGNAL(sliderMoved(int)), this, SLOT(colorLabelUpdateR(int)));
	QObject::connect(g_Slider, SIGNAL(sliderMoved(int)), this, SLOT(colorLabelUpdateG(int)));
	QObject::connect(b_Slider, SIGNAL(sliderMoved(int)), this, SLOT(colorLabelUpdateB(int)));
	QObject::connect(copyFullHexValue, SIGNAL(clicked()), this, SLOT(copyFullHex()));
	QObject::connect(copyWebsafeHexValue, SIGNAL(clicked()), this, SLOT(copyWebsafeHex()));
	QObject::connect(pasteFullHexValue, SIGNAL(clicked()), this, SLOT(pasteFullHex()));
	QObject::connect(hexColorLine, SIGNAL(textEdited(QString)), this, SLOT(fullHexChanged(QString)));
	QObject::connect(CMYK_C_Line, SIGNAL(editingFinished()), this, SLOT(CMYK_C_Edited()));
	QObject::connect(CMYK_M_Line, SIGNAL(editingFinished()), this, SLOT(CMYK_M_Edited()));
	QObject::connect(CMYK_Y_Line, SIGNAL(editingFinished()), this, SLOT(CMYK_Y_Edited()));
	QObject::connect(CMYK_K_Line, SIGNAL(editingFinished()), this, SLOT(CMYK_K_Edited()));
	QObject::connect(r_Line, SIGNAL(editingFinished()), this, SLOT(RGB_R_Edited()));
	QObject::connect(g_Line, SIGNAL(editingFinished()), this, SLOT(RGB_G_Edited()));
	QObject::connect(b_Line, SIGNAL(editingFinished()), this, SLOT(RGB_B_Edited()));
}

void myWindow::colorLabelUpdateR(int r) {
	R = r;
	QString style;
	char *int2char;
	int2char = new char[5];
	char *charLabel;
	charLabel = new char[5];
	style = "background-color: rgb(";
	snprintf(int2char, 5, "%d", R);
	snprintf(charLabel, 5, "%d", R);
	r_Line->setText(charLabel);
	style += int2char;
	style += ", ";
	snprintf(int2char, 5, "%d", G);
	style += int2char;
	style += ", ";
	snprintf(int2char, 5, "%d", B);
	style += int2char;
	style += ");";
	colorLabel->setStyleSheet(style);
	delete[] int2char;
	delete[] charLabel;
	QString fullHexValue;
	fullHexValue = "#";	
	fullHexValue += getHEX();
	hexColorLine->setText(fullHexValue);
	style = "background-color: #";
	style += webSafe();
	style += ";";
	websafeLabel->setStyleSheet(style);
	updateCMYK();
}

void myWindow::colorLabelUpdateG(int g) {
	G = g;
	QString style;
	char *int2char;
	int2char = new char[5];
	char *charLabel;
	charLabel = new char[5];
	style = "background-color: rgb(";
	snprintf(int2char, 5, "%d", R);
	style += int2char;
	style += ", ";
	snprintf(int2char, 5, "%d", G);
	snprintf(charLabel, 5, "%d", G);
	g_Line->setText(charLabel);
	style += int2char;
	style += ", ";
	snprintf(int2char, 5, "%d", B);
	style += int2char;
	style += ");";
	colorLabel->setStyleSheet(style);
	delete[] int2char;
	delete[] charLabel;
	QString fullHexValue;
	fullHexValue = "#";	
	fullHexValue += getHEX();
	hexColorLine->setText(fullHexValue);
	style = "background-color: #";
	style += webSafe();
	style += ";";
	websafeLabel->setStyleSheet(style);
	updateCMYK();
}

void myWindow::colorLabelUpdateB(int b) {
	B = b;
	QString style;
	char *int2char;
	int2char = new char[5];
	char *charLabel;
	charLabel = new char[5];
	style = "background-color: rgb(";
	snprintf(int2char, 5, "%d", R);
	style += int2char;
	style += ", ";
	snprintf(int2char, 5, "%d", G);
	style += int2char;
	style += ", ";
	snprintf(int2char, 5, "%d", B);
	snprintf(charLabel, 5, "%d", B);
	b_Line->setText(charLabel);
	style += int2char;
	style += ");";
	colorLabel->setStyleSheet(style);
	delete[] int2char;
	delete[] charLabel;
	QString fullHexValue;
	fullHexValue = "#";	
	fullHexValue += getHEX();
	hexColorLine->setText(fullHexValue);
	style = "background-color: #";
	style += webSafe();
	style += ";";
	websafeLabel->setStyleSheet(style);
	updateCMYK();
}

void myWindow::updateCMYK() {
	QString CMYK_return;
	QStringList CMYKList;
	CMYK_return = getCMYK();
	CMYKList = CMYK_return.split(",", QString::SkipEmptyParts);
	CMYK_C_Line->setText((CMYKList[0]));
	CMYK_M_Line->setText((CMYKList[1]));
	CMYK_Y_Line->setText((CMYKList[2]));
	CMYK_K_Line->setText((CMYKList[3]));
	CMYK_C = atoi(CMYK_C_Line->text().toStdString().c_str());
	CMYK_M = atoi(CMYK_M_Line->text().toStdString().c_str());
	CMYK_Y = atoi(CMYK_Y_Line->text().toStdString().c_str());
	CMYK_K = atoi(CMYK_K_Line->text().toStdString().c_str());
}

QString getCMYK() {
	QColor *color = new QColor();
	color->setRgb(R, G, B);
	QString CMYK;
	char *tempChar;
	tempChar = new char[6];
	snprintf(tempChar, 5, "%d", color->cyan());
	CMYK = tempChar;
	CMYK += ",";
	snprintf(tempChar, 5, "%d", color->magenta());
	CMYK += tempChar;
	CMYK += ",";
	snprintf(tempChar, 5, "%d", color->yellow());
	CMYK += tempChar;
	CMYK += ",";
	snprintf(tempChar, 5, "%d", color->black());
	CMYK += tempChar;
	return CMYK;
}

QString getHEX() {
	char *hexChar;
	hexChar = new char[8];
	snprintf(hexChar, 8, "%02x%02x%02x", R, G, B);
	return hexChar;
}

QString getRGB() {
	QString rgbString;
	char *rgbValue;
	char *rChar;
	char *gChar;
	char *bChar;
	rChar = new char[5];
	gChar = new char[5];
	bChar = new char[5];
	rgbValue = new char[16];
	unsigned long l;
	rgbValue = ((char*)HEXQString.toStdString().c_str());
	sscanf(rgbValue, "%6lx", &l);
    		snprintf(rChar, 4,  "%d", (int)( l & 0xFF0000 ) >> 16 );
		l <<= 8;
    		snprintf(gChar, 4,  "%d", (int)( l & 0xFF0000 ) >> 16 );
		l <<= 8;
    		snprintf(bChar, 4,  "%d", (int)( l & 0xFF0000 ) >> 16 );
		l <<= 8;
	rgbString = rChar;
	rgbString += ",";
	rgbString += gChar;
	rgbString += ",";
	rgbString += bChar;
	return rgbString;
}

QString myWindow::webSafe() {
	string RGB;
	QString HEX;
	HEX = getHEX();
	RGB = (HEX.at(0)).toAscii();
	RGB += (HEX.at(2)).toAscii();
	RGB += (HEX.at(4)).toAscii();
    for (int ci = 0; ci < 3; ci++) {
       switch (RGB[ci]) {
         case 49:
         RGB[ci]=48;
         break;
         case 50:
         RGB[ci]=51;
         break;
         case 52:
         RGB[ci]=51;
         break;
         case 53:
         RGB[ci]=54;
         break;
         case 55:
         RGB[ci]=54;
         break;
         case 56:
         RGB[ci]=57;
         break;
         case 97:
         RGB[ci]=57;
         break;
         case 98:
         RGB[ci]=99;
         break;
         case 100:
         RGB[ci]=99;
         break;
         case 101:
         RGB[ci]=102;
         break;
      }
   }
	HEX = RGB[0];
	HEX += RGB[0];
	HEX += RGB[1];
	HEX += RGB[1];
	HEX += RGB[2];
	HEX += RGB[2];
	QString HexValue;
	HexValue = "#";
	HexValue += HEX;
	myWindow::hexWebSafeValueLabel->setText(HexValue);
	return HEX;
}


void myWindow::copyFullHex() {
	QClipboard *clipboard = QApplication::clipboard();
	clipboard->setText(hexColorLine->text(), QClipboard::Clipboard);
}

void myWindow::copyWebsafeHex() {
	QClipboard *clipboard = QApplication::clipboard();
	clipboard->setText(hexWebSafeValueLabel->text(), QClipboard::Clipboard);
}

void myWindow::pasteFullHex() {
	const QClipboard *clipboard = QApplication::clipboard();
	const QMimeData *mimeData = clipboard->mimeData();
	QString preserveValue;
	preserveValue = hexColorLine->text();
	QString validHex;
	QString preserveValidHex;
	if (mimeData->hasText()) {
		hexColorLine->setText(clipboard->text());
	}
	if ( hexColorLine->text().length() == 6 || hexColorLine->text().length() == 7 ) {
		validHex = hexColorLine->text();
		preserveValidHex = validHex;
		if (hexColorLine->text().length() == 7) {
			validHex = validHex.right(6);	
		}
		validHex = validHex.toUpper();
		for (int i=0; i<6; i++) { validHex.replace(QString("A"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("B"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("C"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("D"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("E"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("F"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("0"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("1"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("2"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("3"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("4"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("5"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("6"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("7"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("8"), QString("")); }
		for (int i=0; i<6; i++) { validHex.replace(QString("9"), QString("")); }
		}
	HEXQString = preserveValidHex.right(6);	
	hexColorLine->setText(preserveValidHex);
	QString RGB;
	RGB = getRGB();
	QStringList RGBList = RGB.split(",", QString::SkipEmptyParts);
	QString rString = RGBList[0];
	QString gString = RGBList[1];
	QString bString = RGBList[2];
	R = atoi(rString.toStdString().c_str());
	G = atoi(gString.toStdString().c_str());
	B = atoi(bString.toStdString().c_str());
	updateSlider();
	updateCMYK();
	return;
	hexColorLine->setText(preserveValue);
	cout<<"FIXME: Error on invalid value"<<endl;
	return;
}

void myWindow::fullHexChanged(QString str) {
	QString style;
	HEXQString = hexColorLine->text().right(6);	
	if (str.length() == 7) {
	style = "background-color: ";
	style += hexColorLine->text();
	style += ";";
	colorLabel->setStyleSheet(style);
	updateSlider(); }
	return;
}

void myWindow::updateSlider() {
	colorLabelUpdateR(R);
	r_Slider->setValue(R);
	colorLabelUpdateG(G);
	g_Slider->setValue(G);
	colorLabelUpdateB(B);
	b_Slider->setValue(B);
}

void myWindow::CMYK_C_Edited() {
	QString cValue = CMYK_C_Line->text();
	int C = atoi(cValue.toStdString().c_str());
	if (C > 255) {
		CMYK_C_Line->setText("255");
	}
	CMYK_C = atoi(CMYK_C_Line->text().toStdString().c_str());
	updateFromCMYK();
}

void myWindow::CMYK_M_Edited() {
	QString mValue = CMYK_M_Line->text();
	int M = atoi(mValue.toStdString().c_str());
	if (M > 255) {
		CMYK_M_Line->setText("255");
	}
	CMYK_M = atoi(CMYK_M_Line->text().toStdString().c_str());
	updateFromCMYK();
}


void myWindow::CMYK_Y_Edited() {
	QString yValue = CMYK_Y_Line->text();
	int Y = atoi(yValue.toStdString().c_str());
	if (Y > 255) {
		CMYK_Y_Line->setText("255");
	}
	CMYK_Y = atoi(CMYK_Y_Line->text().toStdString().c_str());
	updateFromCMYK();
}


void myWindow::CMYK_K_Edited() {
	QString kValue = CMYK_K_Line->text();
	int K = atoi(kValue.toStdString().c_str());
	if (K > 255) {
		CMYK_K_Line->setText("255");
	}
	CMYK_K = atoi(CMYK_K_Line->text().toStdString().c_str());
	updateFromCMYK();
}

void myWindow::RGB_R_Edited() {
	QString rValue = r_Line->text();
	int r = atoi(rValue.toStdString().c_str());
	if (r > 255) {
		r_Line->setText("255");
	}
	R = atoi(r_Line->text().toStdString().c_str());
	updateFromRGB();

}

void myWindow::RGB_G_Edited() {
	QString gValue = g_Line->text();
	int g = atoi(gValue.toStdString().c_str());
	if (g > 255) {
		g_Line->setText("255");
	}
	G = atoi(g_Line->text().toStdString().c_str());
	updateFromRGB();
}

void myWindow::RGB_B_Edited() {
	QString bValue = b_Line->text();
	int b = atoi(bValue.toStdString().c_str());
	if (b > 255) {
		b_Line->setText("255");
	}
	B = atoi(b_Line->text().toStdString().c_str());
	updateFromRGB();
}

void myWindow::updateFromCMYK() {
	QColor *color = new QColor();
	color->setCmyk(CMYK_C, CMYK_M, CMYK_Y, CMYK_K);
	QString RGB;
	char *tempChar;
	tempChar = new char[6];
	snprintf(tempChar, 5, "%d", color->red());
	RGB = tempChar;
	RGB += ", ";
	snprintf(tempChar, 5, "%d", color->green());
	RGB += tempChar;
	RGB += ", ";
	snprintf(tempChar, 5, "%d", color->blue());
	RGB += tempChar;
	R = color->red();
	G = color->green();
	B = color->blue();
	QString style;
	style = "background-color: rgb(";
	style += RGB;
	style += ");";
	colorLabel->setStyleSheet(style);
	style = "background-color: #";
	style += webSafe();
	style += ";";
	websafeLabel->setStyleSheet(style);
	hexColorLine->setText("#" + getHEX());
	HEXQString = hexColorLine->text().right(6);	
	updateSlider();
}

void myWindow::updateFromRGB() {
	QColor *color = new QColor();
	color->setRgb(R, G, B);
	char *tempChar;
	tempChar = new char[5];
	QString style;
	style = "background-color: rgb(";
	snprintf(tempChar, 5, "%d", R);
	style += tempChar;
	style += ", ";
	snprintf(tempChar, 5, "%d", G);
	style += tempChar;
	style += ", ";
	snprintf(tempChar, 5, "%d", B);
	style += tempChar;
	style += ");";
	colorLabel->setStyleSheet(style);
	style = "background-color: #";
	style += webSafe();
	style += ";";
	websafeLabel->setStyleSheet(style);
	hexColorLine->setText("#" + getHEX());
	HEXQString = hexColorLine->text().right(6);	
	updateSlider();

}

#include "moc_mainwindow.cpp"
#endif // MAINWINDOW_H
